<template>
  <main
    class="noselect"
    @mousemove="mouseMove($event)"
    @touchmove.passive="mouseMove($event)"
  >
    <section ref="spans" class="rowFlex">
      <span ref="innerSpan" class="innerSpan"></span>
    </section>
  </main>
</template>

<script>
export default {
  name: "jellyRun",
  data() {
    return {
      requestAF: () => {
        //运动框架-编辑定时器
        window.requestAnimationFrame =
          window.requestAnimationFrame ||
          function (fn) {
            return setTimeout(fn, 1000 / 60);
          };
        window.cancelAnimationFrame =
          window.cancelAnimationFrame || clearTimeout;
      },
      throttle: false,
      mouse: [0, 0],
    };
  },
  mounted() {
    setTimeout(() => {
      this.spanMove();
    }, 0);
  },
  methods: {
    spanMove() {
      let [x, y] = this.mouse;
      let spans = this.$refs.spans;
      if (spans == null) {
        return false;
      }
      let innerSpan = this.$refs.innerSpan;
      let [wbody, hbody, ls, ws, hs] = [
        document.body.offsetWidth,
        document.body.offsetHeight,
        spans.offsetLeft,
        spans.offsetWidth,
        spans.offsetHeight,
      ];

      let [pointL, pointR, pointM, outerS, innerS] = [
        ls,
        ls + ws,
        ws * 0.5 + ls,
        wbody * 0.12,
        ws * 0.24,
      ];

      let [pointT, pointB, pointMH, outerST, outerSB] = [
        (hbody - hs) * 0.5,
        (hbody + hs) * 0.5,
        hbody * 0.5,
        hbody * 0.03,
        hbody * 0.07,
      ];

      let [t, l, r] = [0, 0, 0];
      let moveL = ls;
      let direction = 0;

      if (y >= pointT - outerST && y <= pointB + outerSB) {
        switch (true) {
          case y <= pointMH:
            t = -((pointT - outerST - y) / hbody) * 100;
            break;
          case y > pointMH:
            t = -((y - pointB - outerSB) / hbody) * 100;
            break;
        }

        switch (true) {
          case x >= pointL - outerS && x < pointM - innerS:
            l = -((pointL - outerS - x) / wbody) * 100;
            break;

          case x >= pointM - innerS && x <= pointM + innerS:
            l = -((x - pointM) / wbody) * 100;
            r = -((pointM - x) / wbody) * 100;
            break;

          case x <= pointR + outerS && x > pointM + innerS:
            r = -((x - pointR - outerS) / wbody) * 100;
            break;
        }

        switch (true) {
          case x >= pointL - outerS && x < pointM:
            direction = x - (pointL - outerS);
            break;
          case x <= pointR + outerS && x > pointM:
            direction =x - (pointR + outerS);
            break;
        }

        let [tl, tr] = [((t * l) ^ 0.5) / 19, ((t * r) ^ 0.5) / 19];

        spans.style.borderRadius =
          37 + tl + "vmin " + (37 + tr) + "vmin " + 10 + "vmin " + 10 + "vmin";

        innerSpan.style.left = -tr / 12 + "vmin";
        innerSpan.style.width = 31 + tl + "vmin";

        moveL = ls + direction / 10;
        moveL < 0 && (moveL = 0);
        moveL > wbody - ws && (moveL = wbody - ws);

        spans.style.left = moveL + "px";
      }

      requestAnimationFrame(this.spanMove);
    },
    mouseMove(e) {
      //节流
      if (this.throttle) {
        requestAnimationFrame(() => {
          this.throttle = false;
        });
        return false;
      }
      this.throttle = true;

      //PC或网页
      let x, y;
      if (e.type == "mousemove") {
        x = e.clientX;
        y = e.clientY;
      } else {
        x = e.touches[0].clientX;
        y = e.touches[0].clientY;
      }

      this.mouse = [x, y];
    },
  },
};
</script>
<style lang="scss" scoped >
section,
.innerSpan {
  position: absolute;
  width: 31vmin;
  height: 19vmin;
  overflow: hidden;
}
section {
  left: calc(50vw - 31vmin * 0.5);
  bottom: calc(#{$vh} * 0.5 - 24vmin * 0.5);

  border-radius: 37vmin 37vmin 10vmin 10vmin;
  box-shadow: 0 1vmin 2.4vmin RGBa(64, 158, 255, 0.24);
  background: radial-gradient(#409eff, white);

  justify-content: center;

  &:before {
    content: ".";
    color: transparent;
    position: relative;
    width: 77%;
    height: 100%;

    border-radius: 37vmin 37vmin 10vmin 10vmin;
    background: radial-gradient(RGBa(64, 158, 255, 0.24), transparent 57%);
  }
}
.innerSpan {
  &:before,
  &:after {
    content: ".";
    color: transparent;
    position: absolute;
    display: block;
    width: 7vmin;
    height: 7vmin;
    left: 7vmin;
    top: 3vmin;

    border-radius: 120% 30% 120% 37%;
    background: rgba(255, 255, 255, 0.12);
  }
  &:after {
    width: 2.8vmin;
    height: 2.8vmin;
    left: 7vmin;
    top: 3.4vmin;

    border-radius: 240% 50% 240% 50%;
    background: rgba(255, 255, 255, 0.88);
  }
}
</style>
